﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SDCloudSolution.SDCloud.Web.Infrastructure;
using SDCloudSolution.SDCloud.Web.Infrastructure.Interfaces;

namespace SDCloudSolution.SDCloud.Web.UnitTests.Infrastructure
{
    [TestClass]
    public class DataSizeFormatterTests
    {
        private IDataSizeFormatter _target;

        [TestInitialize]
        public void TestInitialize()
        {
            _target = new DataSizeFormatter();
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException), AllowDerivedTypes = true)]
        public void ConvertBytesToUserFriendlyFormat_NegativeBytesGiven_ShouldThrowException()
        {
            _target.ConvertBytesToUserFriendlyFormat(-100);
        }

        [TestMethod]
        public void ConvertBytesToUserFriendlyFormat_ZeroBytesGiven_ShouldReturnBytePostfix()
        {
            var result = _target.ConvertBytesToUserFriendlyFormat(0);

            AssertCorrectFormat(0.0, "B", result);
        }

        [TestMethod]
        public void ConvertBytesToUserFriendlyFormat_TwoByteGiven_ShouldReturnBytePostfix()
        {
            var result = _target.ConvertBytesToUserFriendlyFormat(2);

            AssertCorrectFormat(2.0, "B", result);
        }

        [TestMethod]
        public void ConvertBytesToUserFriendlyFormat_TwoKiloBytesGiven_ShouldReturnKBytesPostfix()
        {
            var result = _target.ConvertBytesToUserFriendlyFormat(2050);

            AssertCorrectFormat(2.0, "KB", result);
        }

        [TestMethod]
        public void ConvertBytesToUserFriendlyFormat_TwoMegaBytesGiven_ShouldReturnMBytesPostfix()
        {
            var result = _target.ConvertBytesToUserFriendlyFormat(2097158);

            AssertCorrectFormat(2.0, "MB", result);
        }

        [TestMethod]
        public void ConvertBytesToUserFriendlyFormat_TwoGigaBytesGiven_ShouldReturnGBytesPostfix()
        {
            var result = _target.ConvertBytesToUserFriendlyFormat(2147483650);

            AssertCorrectFormat(2.0, "GB", result);
        }

        [TestMethod]
        public void ConvertBytesToUserFriendlyFormat_TwoTeraBytesGiven_ShouldReturnTBytesPostfix()
        {
            var result = _target.ConvertBytesToUserFriendlyFormat(2199023255554);

            AssertCorrectFormat(2.0, "TB", result);
        }

        [TestMethod]
        public void ConvertBytesToUserFriendlyFormat_TwoPetaBytesGiven_ShouldReturnTBytesPostfix()
        {
            var result = _target.ConvertBytesToUserFriendlyFormat(2251799813685248);

            AssertCorrectFormat(2048.0, "TB", result);
        }

        private static void AssertCorrectFormat(double expectedDisplayedValue, string expectedPostfix, string actualValue, double accuracy = 0.1d)
        {
            var parts = actualValue.Split(' ');
            Assert.IsNotNull(parts);
            Assert.AreEqual(2, parts.Length);
            Assert.AreEqual(expectedPostfix, parts[1]);

            double actualDisplayedValue;
            var isValidDouble = double.TryParse(parts[0], out actualDisplayedValue);
            Assert.IsTrue(isValidDouble);
            Assert.AreEqual(expectedDisplayedValue, actualDisplayedValue, accuracy);
        }
    }
}
